<?php

// движок — это наше все!
require_once 'htmlMimeMail5/htmlMimeMail5.php';

/**
 * Заготовка почтового сообщения
 *
 */
class Kernel_Mail_Message extends Kernel_Component {

    /**
     * Наименование шаблона в базе данных (если используется).
     *
     * @var string
     */
    public $name;

    /**
     * Отправитель сообщения
     *
     * @var string
     */
    public $from;

    /**
     * Получатель(ли) сообщения
     *
     * @var mixed
     */
    public $to;

    /**
     * Шаблон сообщения - строка вида 'Hello {$fname}!'
     *
     * @var string
     */
    protected $_subject;

    /**
     * Путь к файлу шаблона для HTML-части
     *
     * @var string
     */
    protected $_html_template;

    /**
     * Путь к файлу шаблона для текстовой части
     *
     * @var string
     */
    protected $_text_template;

    /**
     * Набор переменных шаблона для формирования сообщения
     *
     * @var array
     */
    protected $_vars = array();

    /**
     * Набор символов заголовков
     *
     * @var string
     */
    private $_head_charset = 'utf-8';

    /**
     * Набор символов текстовой части
     *
     * @var string
     */
    private $_text_charset = 'utf-8';

    /**
     * Набор символов HTML-части
     *
     * @var string
     */
    private $_html_charset = 'utf-8';

    /**
     * Конструктор.
     *
     */
    public function __construct($params = array()) {

        // получаем значение по умолчанию для поля "отправитель"
        $this->from = Kernel_Config::get('mail', 'from');
        parent::__construct($params);
        if (!is_null($this->name)) {
            $this->_defineTemplates();
        }
        // сразу определяем почтовый хост по умолчанию
        $this->assign(array('HOST' => $this->_getHost()));
    }

    /**
     * Устанавливает набор переменных шаблона для формирования сообщения.
     *
     * @param   array   $vars
     * @return  Kernel_Mail_Message
     */
    public function assign($vars) {
        $this->_vars = array_merge($this->_vars, $vars);
        return $this;
    }

    /**
     * Отправляет сообщение, возвращает результат отправки.
     *
     * @return  boolean
     */
    public function send() {
        $mail = new htmlMimeMail5;
        $mail->setHeadCharset($this->_head_charset);

        // генерируеим и выставляем отправителя сообщения
        $mail->setFrom($this->_fromTemplate($this->from));

        // генерируеим и выставляем тему сообщения
        $mail->setSubject($this->_fromTemplate($this->_subject));

        // если указан шаблон текстовой части
        if (!is_null($this->_text_template)) {
            $mail->setTextCharset($this->_text_charset);
            $mail->setText($this->_compose($this->_text_template));
        }

        // если указан шаблон HTML-части
        if (!is_null($this->_html_template)) {
            $mail->setHTMLCharset($this->_html_charset);
            $mail->setHTML($this->_compose($this->_html_template));
        }

        return $mail->send(array_map(array($this, '_fromTemplate'), (array)$this->to));
    }

    /**
     * Формирует фрагмент сообщения по указанному шаблону.
     *
     * @param   string  $template
     * @return  string
     */
    private function _compose($template) {
        $smarty = Kernel_Response_Html::createEngine();
        $smarty->assign($this->_vars + array(
            // передаем основной путь для формирования ссылок на страницы фронтенда
            'BASE_PATH' => BASE_PATH,
        ));
        return $smarty->fetch($template);
    }

    /**
     * Формирует строку из шаблона. Как смарти, просто заменяет наименования
     * переменных на их значения.
     *
     * @param   string  $template
     * @return  string
     */
    private function _fromTemplate($template) {
        return preg_replace('/\{\$([^\}]+)\}/e', '$this->_vars["$1"]', $template);
    }

    /**
     * Возвращает имя почтового хоста по умолчанию.
     *
     * @return  string
     */
    private function _getHost() {
        return preg_replace('/^www\./', '', $_SERVER['HTTP_HOST']);
    }

    /**
     * Устанавливает наименования шаблонов, если шаблон — редактируемый.
     *
     */
    private function _defineTemplates() {
        require_once KERNEL_PATH . '/plugins/resource.db.php';

        // читаем содержимое поля "subject" прямо в переменную — мы разбираем его без смарти
        $this->_subject = smarty_resource_db_get($this->name, 'subject');

        // выставляем текстовый шаблон, если он непустой
        $this->_text_template = smarty_resource_db_defined($this->name, 'text')
            ? 'db:' . $this->name . '.text' : null;

        // выставляем html-ный шаблон, если он непустой
        $this->_html_template = smarty_resource_db_defined($this->name, 'html')
            ? 'db:' . $this->name . '.html' : null;
    }
}
